Amazon FSx for NetApp ONTAPをマウントしたWindows ServerをSFTPサーバーとして動作させてみた

Amazon FSx for NetApp ONTAPをマウントしたWindows ServerをSFTPサーバーとして動作させてみた

FSxNにSFTPで接続したい場合は運用や周囲の環境を変更できないかも検討しよう
Clock Icon2024.08.20

Amazon FSx for NetApp ONTAPにSFTPでファイルを配置したい

こんにちは、のんピ(@non____97)です。

皆さんはAmazon FSx for NetApp ONTAP(以降FSxN)にSFTPでファイルを配置したいと思ったことはありますか? 私はあります。

FSxNに対してSFTPでファイル操作を行いたいシチュエーションとして以下が挙げられます。

  • 通信を暗号化したいが、以下条件からSMBやNFSの暗号化の機能を使用できない
    • 暗号化に必要なパッケージをインストールできない
    • OSが古い
  • ネットワーク的にNFSやSMBのポートが開けられない
  • 既存の仕組みがSFTPベースで処理を行っており、その処理を継続利用したい

ただし、残念ならがFSxNではSFTPをサポートしていません。NetAppのKBにもONTAP 9はSFTPをサポートしていないことが紹介されています。

原因
ONTAPでは SFTP経由のデータアクセスはサポートされない

SFTPを使用してONTAP 9のデータにアクセスできません - NetApp

では、どうしたら良いでしょうか。

一つの解はFSxNをマウントしたEC2インスタンスをSFTPサーバーとして動作させるものだと考えます。

ちょうど以下記事と同じ発想です。

https://dev.classmethod.jp/articles/mountpoint-s3-ec2-sftp-server/

実際にそのようなことが可能なのか確認してみます。

いきなりまとめ

  • FSxNをマウントしたWindows ServerをSFTPサーバーとして動作させることは可能
  • デフォルトではいずれのドメインユーザーでもSFTPで接続ができる
    • 必ずAllowGroupsやAllowUsersで絞ろう
  • chrootはSMBファイル共有との兼ね合いで設定できない
  • 鍵認証をした場合、FSxNのSMBファイル共有にはアクセスできない
    • Kerberos認証が求められる都合上、パスワードを使った認証が必要
  • Windows Server自体にドメインユーザー毎に登録した公開鍵を使って鍵認証を行うことは可能
    • ただし、2024/8/20でWindows標準で提供されているOpenSSH 8.1p1は未対応
      • AuthorizedKeysCommandが使用できないため
    • ベータ版のOpenSSH 8.6以降を使用する必要がある
    • ADのスキーマ拡張を行う必要もあるため作業は慎重に

やってみた

検証環境

検証環境は以下のとおりです。

Amazon FSx for NetApp ONTAPをマウントしたWindows ServerをSFTPサーバーとして動作させてみた検証環境構成図.png

AD DCについては以下記事の検証で使用したものを流用します。

https://dev.classmethod.jp/articles/amazon-fsx-for-netapp-ontap-delegated-file-system-administrators-group/

ドメインユーザーについては以下記事で作成したものを使用しています。

https://dev.classmethod.jp/articles/amazon-fsx-for-netapp-ontap-access-based-enumeration/

SFTPサーバー用Windows Serverのドメイン参加

SFTPサーバー用Windows ServerをActive Directoryにドメイン参加させます。

作業は以下記事を参考に行います。

https://dev.classmethod.jp/articles/able-to-join-a-domain-even-when-the-time-zone-is-different-from-domain-controller

作業はSSMセッションマネージャーで接続して行いました。

# 現在のDNSサーバーの設定確認
> Get-DnsClientServerAddress

InterfaceAlias               Interface Address ServerAddresses
                             Index     Family
--------------               --------- ------- ---------------
Ethernet 3                           5 IPv4    {10.0.0.2}
Ethernet 3                           5 IPv6    {}
Loopback Pseudo-Interface 1          1 IPv4    {}
Loopback Pseudo-Interface 1          1 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::2, fec0:0:0:ffff::3}

# DNSサーバーとしてAD DCを参照するように変更
> Set-DnsClientServerAddress -InterfaceIndex 5 -ServerAddresses ("10.0.0.139")
> Get-DnsClientServerAddress

InterfaceAlias               Interface Address ServerAddresses
                             Index     Family
--------------               --------- ------- ---------------
Ethernet 3                           5 IPv4    {10.0.0.139}
Ethernet 3                           5 IPv6    {}
Loopback Pseudo-Interface 1          1 IPv4    {}
Loopback Pseudo-Interface 1          1 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::2, fec0:0:0:ffff::3}

# ドメイン参加
> $password=ConvertTo-SecureString -AsPlainText -Force "<ドメインのAdministratorのパスワード>"
> $credential=New-Object System.Management.Automation.PSCredential("corp.non-97.net\Administrator",$password)
> Add-Computer -DomainName corp.non-97.net -Credential $credential -Restart -Force

OS再起動後にドメインのAdministratorでRDP接続し、ドメイン参加できたことを確認します。

SFTPサーバー用Windows ServerへOpenSSHをインストール

続いてSFTPサーバー用Windows ServerへOpenSSHをインストールを行います。

WindowsにおけるOpenSSHの注意点は以下にまとまっています。使用できない構文がいくつかあるので注意しましょう。

https://learn.microsoft.com/ja-jp/windows-server/administration/openssh/openssh_server_configuration

Powershellを使ってインストールします。

> Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'
Name  : OpenSSH.Client~~~~0.0.1.0
State : Installed

Name  : OpenSSH.Server~~~~0.0.1.0
State : NotPresent

> Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

Path          :
Online        : True
RestartNeeded : False

インストールできました。

sshdサービスの起動および、自動起動の有効化を行います。

> Start-Service sshd
WARNING: Waiting for service 'OpenSSH SSH Server (sshd)' to start...

> Set-Service -Name sshd -StartupType 'Automatic'

> Get-Service sshd |
  Select-Object * | 
  Format-List |
  Out-String -Stream | 
  ?{$_ -ne ""}
Name                : sshd
RequiredServices    : {}
CanPauseAndContinue : False
CanShutdown         : False
CanStop             : True
DisplayName         : OpenSSH SSH Server
DependentServices   : {}
MachineName         : .
ServiceName         : sshd
ServicesDependedOn  : {}
ServiceHandle       : SafeServiceHandle
Status              : Running
ServiceType         : Win32OwnProcess
StartType           : Automatic
Site                :
Container           :

SFTPで接続

一度試しにSFTPで接続してみましょう。

ドメインのAdministratorの認証情報を使って接続をします。

>  sftp 'corp.non-97.net\Administrator'@ec2-54-87-31-68.compute-1.amazonaws.com
corp.non-97.net\Administrator@ec2-54-87-31-68.compute-1.amazonaws.com's password:
Connected to ec2-54-87-31-68.compute-1.amazonaws.com.
sftp>
sftp> pwd
Remote working directory: /C:/Users/Administrator.CORP
sftp> ls -l
dr-x******    1 -        -               0 Aug 16 09:52 3D Objects
drwx******    1 -        -               0 Aug 19  2021 AppData
drwx******    1 -        -               0 Aug 16 09:51 Application Data
dr-x******    1 -        -               0 Aug 16 09:52 Contacts
drwx******    1 -        -               0 Aug 16 09:51 Cookies
dr-x******    1 -        -            4096 Aug 16 09:52 Desktop
dr-x******    1 -        -            4096 Aug 16 09:52 Documents
dr-x******    1 -        -               0 Aug 16 09:52 Downloads
dr-x******    1 -        -               0 Aug 16 09:52 Favorites
dr-x******    1 -        -               0 Aug 16 09:52 Links
drwx******    1 -        -               0 Aug 16 09:51 Local Settings
dr-x******    1 -        -               0 Aug 16 09:52 Music
drwx******    1 -        -               0 Aug 16 09:51 My Documents
-rw-******    1 -        -          786432 Aug 16 08:43 NTUSER.DAT
-rw-******    1 -        -           65536 Aug 16 09:51 NTUSER.DAT{cb2c9905-007c-11ec-b8ea-cc31a8606de8}.TM.blf
-rw-******    1 -        -          524288 Aug 16 09:51 NTUSER.DAT{cb2c9905-007c-11ec-b8ea-cc31a8606de8}.TMContainer00000000000000000001.regtrans-ms
-rw-******    1 -        -          524288 Aug 16 09:51 NTUSER.DAT{cb2c9905-007c-11ec-b8ea-cc31a8606de8}.TMContainer00000000000000000002.regtrans-ms
drwx******    1 -        -               0 Aug 16 09:51 NetHood
dr-x******    1 -        -               0 Aug 16 09:52 Pictures
drwx******    1 -        -               0 Aug 16 09:51 PrintHood
drwx******    1 -        -               0 Aug 16 09:51 Recent
dr-x******    1 -        -               0 Aug 16 09:52 Saved Games
dr-x******    1 -        -               0 Aug 16 09:52 Searches
drwx******    1 -        -               0 Aug 16 09:51 SendTo
drwx******    1 -        -               0 Aug 16 09:51 Start Menu
drwx******    1 -        -               0 Aug 16 09:51 Templates
dr-x******    1 -        -               0 Aug 16 09:52 Videos
-rw-******    1 -        -          163840 Aug 16 09:51 ntuser.dat.LOG1
-rw-******    1 -        -          237568 Aug 16 09:51 ntuser.dat.LOG2
-rw-******    1 -        -              20 Aug 19  2021 ntuser.ini

続いて、test-user01でも接続できるか確認します。

> sftp 'corp.non-97.net\test-user01'@ec2-52-201-249-4.compute-1.amazonaws.com
corp.non-97.net\test-user01@ec2-52-201-249-4.compute-1.amazonaws.com's password:
Connected to ec2-52-201-249-4.compute-1.amazonaws.com.
sftp> ls -l
drwx******    1 -        -               0 Aug 19  2021 AppData
drwx******    1 -        -               0 Aug 16 12:44 Application Data
drwx******    1 -        -               0 Aug 16 12:44 Cookies
dr-x******    1 -        -               0 Aug 19  2021 Desktop
dr-x******    1 -        -            4096 Aug 16 12:44 Documents
.
.
(中略)
.
.
dr-x******    1 -        -               0 May  8  2021 Videos
-rw-******    1 -        -          454656 Aug 16 12:44 ntuser.dat.LOG1
-rw-******    1 -        -               0 Aug 16 12:44 ntuser.dat.LOG2
-rw-******    1 -        -              20 Aug 19  2021 ntuser.ini
sftp> pwd
Remote working directory: /C:/Users/test-user01
sftp> cd ../../
sftp> pwd
Remote working directory: /C:/
sftp> ls -l
drwx******    1 -        -               0 Aug 16 09:52 $Recycle.Bin
-rw-******    1 -        -               0 Jan 10  2024 $WINRE_BACKUP_PARTITION.MARKER
drwx******    1 -        -               0 Jul 10 03:33 $WinREAgent
-rw-******    1 -        -               1 May  8  2021 BOOTNXT
drwx******    1 -        -            8192 Jul 10 03:43 Boot
drwx******    1 -        -               0 Aug 18  2021 Documents and Settings
drwx******    1 -        -               0 Aug 19  2021 EFI
drwx******    1 -        -               0 May  8  2021 PerfLogs
dr-x******    1 -        -            4096 Aug 19  2021 Program Files
drwx******    1 -        -            4096 Jul 12  2023 Program Files (x86)
drwx******    1 -        -            4096 Aug 16 09:49 ProgramData
drwx******    1 -        -               0 Aug 16 08:42 Recovery
drwx******    1 -        -            4096 Aug 16 08:44 System Volume Information
dr-x******    1 -        -            4096 Aug 16 12:44 Users
drwx******    1 -        -           16384 Aug 16 08:42 Windows
-r--******    1 -        -          440456 Jul 10 03:38 bootmgr

# 他ユーザーの領域にはアクセスできないこと
sftp> cd Users/Administrator
sftp> ls -l
remote readdir("/C:/Users/Administrator"): Bad message
sftp> cd ../Public
sftp> ls -l
remote readdir("/C:/Users/Public"): Bad message

Windows ServerにRDP接続をしていないドメインユーザーでもSFTPで接続できました。test-user01はDomain Adminsには属していないユーザーです。

1.test-user01 Member Of.png

現在のC:\Users配下は以下のとおりです。test-user01用のフォルダが作成されていますね。

2.現在のUsers.png

同様にtest-user02でもSFTPで接続できることを確認します。

> sftp 'corp.non-97.net\test-user02'@ec2-52-201-249-4.compute-1.amazonaws.com
corp.non-97.net\test-user02@ec2-52-201-249-4.compute-1.amazonaws.com's password:
Connected to ec2-52-201-249-4.compute-1.amazonaws.com.
sftp> pwd
Remote working directory: /C:/Users/test-user02

test-user02のフォルダも作成されました。

3.Usersにtest-user02が追加された.png

デフォルトではいずれのドメインユーザーもSFTPで接続できてしまうのでしょうか。それとも、確認したユーザーがFSxAdminGroupというグループに所属しているのが関係あるのでしょうか。FSxAdminGroupはRDP用のグループに所属しています。

4.FSxAdminGroupのMember Of.png

test-user03という必要最低限のグループにしか所属していないドメインユーザーを作成します。

5.test-user03の作成.png

test-user03で接続します。

>  sftp 'corp.non-97.net\test-user03'@ec2-52-201-249-4.compute-1.amazonaws.com
corp.non-97.net\test-user03@ec2-52-201-249-4.compute-1.amazonaws.com's password:
Connected to ec2-52-201-249-4.compute-1.amazonaws.com.
sftp> pwd
Remote working directory: /C:/Users/test-user03

接続できました。ということで、デフォルトではいずれのドメインユーザーでもSFTPで接続ができるようです。

sshd_configの変更

いずれのドメインユーザーでも接続できてしまうのではよろしくありません。

sshd_configを変更して制御します。sshd_configはC:\ProgramData\ssh\sshd_configに存在します。

Domain AdminsとFSxAdminGroupというグループに所属するもののみ許可するように変更します。また、各グループにてchrootを設定します。

具体的にはファイルの末尾を以下のように変更します。

C\ProgramData\ssh\sshd_config
AllowGroups "corp\Domain Admins" corp\FsxAdminGroup

Match Group "corp\Domain Admins"
       ChrootDirectory C:\
       ForceCommand internal-sftp

Match Group "corp\FsxAdminGroup"
       ChrootDirectory C:\ProgramData\Amazon
       ForceCommand internal-sftp

sshdを再起動します。

> Restart-Service sshd

接続確認をしましょう。

ドメインのAdministratorの場合
>  sftp 'corp.non-97.net\Administrator'@ec2-52-201-249-4.compute-1.amazonaws.com
corp.non-97.net\Administrator@ec2-52-201-249-4.compute-1.amazonaws.com's password:
Connected to ec2-52-201-249-4.compute-1.amazonaws.com.
sftp> pwd
Remote working directory: /
sftp> ls -l
drwx******    1 -        -               0 Aug 16 09:52 $Recycle.Bin
-rw-******    1 -        -               0 Jan 10  2024 $WINRE_BACKUP_PARTITION.MARKER
drwx******    1 -        -               0 Jul 10 03:33 $WinREAgent
-rw-******    1 -        -               1 May  8  2021 BOOTNXT
drwx******    1 -        -            8192 Jul 10 03:43 Boot
drwx******    1 -        -               0 Aug 18  2021 Documents and Settings
drwx******    1 -        -               0 Aug 19  2021 EFI
drwx******    1 -        -               0 May  8  2021 PerfLogs
dr-x******    1 -        -            4096 Aug 19  2021 Program Files
drwx******    1 -        -            4096 Jul 12  2023 Program Files (x86)
drwx******    1 -        -            4096 Aug 16 09:49 ProgramData
drwx******    1 -        -               0 Aug 16 08:42 Recovery
drwx******    1 -        -            4096 Aug 16 08:44 System Volume Information
dr-x******    1 -        -            4096 Aug 16 12:56 Users
drwx******    1 -        -           16384 Aug 16 08:42 Windows
-r--******    1 -        -          440456 Jul 10 03:38 bootmgr
test-user01の場合
>  sftp 'corp.non-97.net\test-user01'@ec2-52-201-249-4.compute-1.amazonaws.com
corp.non-97.net\test-user01@ec2-52-201-249-4.compute-1.amazonaws.com's password:
Connected to ec2-52-201-249-4.compute-1.amazonaws.com.
sftp> pwd
Remote working directory: /
sftp> ls -l
drwx******    1 -        -               0 Jul 10 03:58 AWSUpdateWindowsInstance
drwx******    1 -        -            4096 Aug 16 08:42 EC2Launch
drwx******    1 -        -            4096 Aug 16 09:30 SSM
drwx******    1 -        -               0 Nov 17  2021 tools
test-user02の場合
>  sftp 'corp.non-97.net\test-user02'@ec2-52-201-249-4.compute-1.amazonaws.com
corp.non-97.net\test-user02@ec2-52-201-249-4.compute-1.amazonaws.com's password:
Connected to ec2-52-201-249-4.compute-1.amazonaws.com.
sftp> pwd
Remote working directory: /
sftp> ls -l
drwx******    1 -        -               0 Jul 10 03:58 AWSUpdateWindowsInstance
drwx******    1 -        -            4096 Aug 16 08:42 EC2Launch
drwx******    1 -        -            4096 Aug 16 09:30 SSM
drwx******    1 -        -               0 Nov 17  2021 tools
test-user03の場合
>  sftp 'corp.non-97.net\test-user03'@ec2-52-201-249-4.compute-1.amazonaws.com
corp.non-97.net\test-user03@ec2-52-201-249-4.compute-1.amazonaws.com's password:
Permission denied, please try again.

AllowGroupsで許可されているグループに所属しているユーザーのみSFTPで接続できました。また、接続できたものについてはchrootが効いていることが分かります。

念の為、SSHでは接続できないことも確認しておきましょう。

>  ssh 'corp.non-97.net\Administrator'@ec2-52-201-249-4.compute-1.amazonaws.com
corp.non-97.net\Administrator@ec2-52-201-249-4.compute-1.amazonaws.com's password:
This service allows sftp connections only.
Connection to ec2-52-201-249-4.compute-1.amazonaws.com closed.

>  ssh 'corp.non-97.net\test-user01'@ec2-52-201-249-4.compute-1.amazonaws.com
corp.non-97.net\test-user01@ec2-52-201-249-4.compute-1.amazonaws.com's password:
This service allows sftp connections only.
Connection to ec2-52-201-249-4.compute-1.amazonaws.com closed.

はい、弾かれました。意図したとおりです。

ファイル共有の作成

FSxNでファイル共有を作成します。

FSxNファイルシステムにSSHで接続して、ONTAP CLIで操作します。

SMBサーバーがドメイン参加していることを確認します。

$ ssh fsxadmin@management.fs-0480a4843e2853b1f.fsx.us-east-1.amazonaws.com
(fsxadmin@management.fs-0480a4843e2853b1f.fsx.us-east-1.amazonaws.com) Password:

Last login time: 8/16/2024 06:23:42
::> set diag

Warning: These diagnostic commands are for use by NetApp personnel only.
Do you want to continue? {y|n}: y

::*> cifs show -instance

                                          Vserver: svm
                         CIFS Server NetBIOS Name: SMB-SERVER
                    NetBIOS Domain/Workgroup Name: CORP
                      Fully Qualified Domain Name: CORP.NON-97.NET
                              Organizational Unit: OU=FSxForONTAP,DC=corp,DC=non-97,DC=net
Default Site Used by LIFs Without Site Membership:
                                   Workgroup Name: -
                                   Kerberos Realm: -
                             Authentication Style: domain
                CIFS Server Administrative Status: up
                          CIFS Server Description:
                          List of NetBIOS Aliases: -

::*> volume show -security-style ntfs -fields security-style, junction-path
vserver volume   security-style junction-path
------- -------- -------------- -------------
svm     vol_ntfs ntfs           /vol_ntfs

::*> cifs share show
Vserver        Share         Path              Properties Comment  ACL
-------------- ------------- ----------------- ---------- -------- -----------
svm            c$            /                 oplocks    -        BUILTIN\Administrators / Full Control
                                               browsable
                                               changenotify
                                               show-previous-versions
svm            ipc$          /                 browsable  -        -
2 entries were displayed.

SMBのファイル共有を作成するにあたって、/vol_ntfs配下に各ファイル共有に対応したサブフォルダを作成します。

> New-PSDrive -Name "Z" -PSProvider FileSystem -Root "\\SMB-SERVER.corp.non-97.net\c$" -Persist

Name           Used (GB)     Free (GB) Provider      Root                                               CurrentLocation
----           ---------     --------- --------      ----                                               ---------------
Z                   0.00          0.95 FileSystem    \\SMB-SERVER.corp.non-97.net\c$

> ls Z:\

    Directory: Z:\

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----l         8/16/2024   6:22 AM                vol_ntfs
d----l         8/16/2024   5:06 AM                vol_unix

> mkdir Z:\vol_ntfs\share1
> mkdir Z:\vol_ntfs\share2
> mkdir Z:\vol_ntfs\share3

ONTAP CLIに戻って、用意したサブフォルダをパスとするファイル共有を作成します。

::*> cifs share create -vserver svm -share-name share1 -path /vol_ntfs/share1

::*> cifs share create -vserver svm -share-name share2 -path /vol_ntfs/share2

::*> cifs share create -vserver svm -share-name share3 -path /vol_ntfs/share3

::*> cifs share show
Vserver        Share         Path              Properties Comment  ACL
-------------- ------------- ----------------- ---------- -------- -----------
svm            c$            /                 oplocks    -        BUILTIN\Administrators / Full Control
                                               browsable
                                               changenotify
                                               show-previous-versions
svm            ipc$          /                 browsable  -        -
svm            share1        /vol_ntfs/share1  oplocks    -        Everyone / Full Control
                                               browsable
                                               changenotify
                                               show-previous-versions
svm            share2        /vol_ntfs/share2  oplocks    -        Everyone / Full Control
                                               browsable
                                               changenotify
                                               show-previous-versions
svm            share3        /vol_ntfs/share3  oplocks    -        Everyone / Full Control
                                               browsable
                                               changenotify
                                               show-previous-versions
5 entries were displayed.

ファイル共有のACLによってアクセス制限されることを確認したいので、ACLを変更します。また、ABEも有効化しておきます。

::*> cifs share properties add -share-name share* -share-properties access-based-enumeration
3 entries were acted on.

::*> cifs share access-control create -share share2 -user-or-group BUILTIN\Administrators -user-group-type windows -permission Full_Control

::*> cifs share access-control create -share share2 -user-or-group CORP\FSxAdminGroup -user-group-type windows -permission Full_Control

::*> cifs share access-control delete -share share2 -user-or-group Everyone

::*> cifs share access-control create -share share3 -user-or-group BUILTIN\Administrators -user-group-type windows -permission Full_Control

::*> cifs share access-control create -share share3 -user-or-group CORP\test-user03 -user-group-type windows -permission READ

::*> cifs share access-control delete -share share3 -user-or-group Everyone

::*> cifs share show
Vserver        Share         Path              Properties Comment  ACL
-------------- ------------- ----------------- ---------- -------- -----------
svm            c$            /                 oplocks    -        BUILTIN\Administrators / Full Control
                                               browsable
                                               changenotify
                                               show-previous-versions
svm            ipc$          /                 browsable  -        -
svm            share1        /vol_ntfs/share1  oplocks    -        Everyone / Full Control
                                               browsable
                                               changenotify
                                               access-based-enumeration
                                               show-previous-versions
svm            share2        /vol_ntfs/share2  oplocks    -        BUILTIN\Administrators / Full Control
                                               browsable           CORP\FSxAdminGroup / Full Control
                                               changenotify
                                               access-based-enumeration
                                               show-previous-versions
svm            share3        /vol_ntfs/share3  oplocks    -        BUILTIN\Administrators / Full Control
                                               browsable           CORP\test-user03 / Read
                                               changenotify
                                               access-based-enumeration
                                               show-previous-versions
5 entries were displayed.

シンボリックリンクの作成

ファイル共有へのシンボリックリンクを作成します。

SMBファイル共有にアクセスする際はネットワークドライブにマウントするのが一般的だとは思いますが、ネットワークドライブはユーザーそれぞれに設定する必要があります。

グループポリシーで設定するのも手かもしれませんが非常に手間です。ということでSMBファイル共有へのシンボリックリンクを作成して対応します。

> mkdir C:\fsxn-share

    Directory: C:\

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         8/18/2024   6:41 AM                fsxn-share

> New-Item -ItemType SymbolicLink -Path C:\fsxn-share\share1 -Value \\SMB-SERVER.corp.non-97.net\share1
> New-Item -ItemType SymbolicLink -Path C:\fsxn-share\share2 -Value \\SMB-SERVER.corp.non-97.net\share2
> New-Item -ItemType SymbolicLink -Path C:\fsxn-share\share3 -Value \\SMB-SERVER.corp.non-97.net\share3

> ls C:\fsxn-share

    Directory: C:\fsxn-share

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----l         8/18/2024   6:47 AM                share1
d----l         8/18/2024   6:48 AM                share2
d----l         8/18/2024   6:48 AM                share3

シンボリックリンク先のSMBファイル共有へアクセス

シンボリックリンク先のSMBファイル共有へアクセスできるか確認します。

sshd_configの末尾の設定は以下のようにしています。

sshd_config
AllowGroups "corp\Domain Admins" corp\FsxAdminGroup corp\domain-local

Match Group corp\*
       ChrootDirectory C:\fsxn-share\
       ForceCommand internal-sftp

一旦、chrootで絞っています。シンボリックリンク先が外部のSMBファイル共有なので接続できないとは思いますが、一旦試します。

また、corp\domain-localというグループにはtest-user03を所属させています。

6.test-user03をdomain-localに所属させる.png

SFTPで接続して、SMBファイル共有のシンボリックリンクであるshare1配下にPUTしようとします。

>  sftp 'corp\Administrator'@ec2-52-201-249-4.compute-1.amazonaws.com
corp\Administrator@ec2-52-201-249-4.compute-1.amazonaws.com's password:
Connected to ec2-52-201-249-4.compute-1.amazonaws.com.
sftp> pwd
Remote working directory: /
sftp> ls -l
lrwx******    1 -        -               0 Aug 18 06:47 share1
lrwx******    1 -        -               0 Aug 18 06:48 share2
lrwx******    1 -        -               0 Aug 18 06:48 share3
sftp> put test.txt share1/test.txt
Uploading test.txt to /share1/test.txt
dest open "/share1/test.txt": Permission denied

はい拒否されました。やはり、chrootをかけている環境においては外部のSMBファイル共有へアクセスすることはできないようです。

chrootを外して再チャレンジします。

sshd_config
AllowGroups "corp\Domain Admins" corp\FsxAdminGroup corp\domain-local

Match Group corp\*
       ForceCommand internal-sftp

実行結果は以下のとおりです。

ドメインのAdministrator
>  sftp 'corp\Administrator'@ec2-52-201-249-4.compute-1.amazonaws.com
corp\Administrator@ec2-52-201-249-4.compute-1.amazonaws.com's password:
Connected to ec2-52-201-249-4.compute-1.amazonaws.com.
sftp> cd ../../fsxn-share
sftp> ls -l
lrwx******    1 -        -               0 Aug 18 07:57 share1
lrwx******    1 -        -               0 Aug 18 07:57 share2
lrwx******    1 -        -               0 Aug 18 07:57 share3
sftp>
sftp> put test.txt share1/test.txt
Uploading test.txt to /C:/fsxn-share/share1/test.txt
test.txt                      100%    5     0.0KB/s   00:00
sftp> put test.txt share2/test.txt
Uploading test.txt to /C:/fsxn-share/share2/test.txt
test.txt                      100%    5     0.0KB/s   00:00
sftp> put test.txt share3/test.txt
Uploading test.txt to /C:/fsxn-share/share3/test.txt
test.txt                      100%    5     0.0KB/s   00:00
sftp>
sftp> ls -l share1
-rw-******    1 -        -               5 Aug 18 07:58 test.txt
sftp>
sftp> get share1/test.txt .
Fetching /C:/fsxn-share/share1/test.txt to ./test.txt
test.txt                      100%    5     0.0KB/s   00:00
test-user01
>  sftp 'corp.non-97.net\test-user01'@ec2-52-201-249-4.compute-1.amazonaws.com
corp.non-97.net\test-user01@ec2-52-201-249-4.compute-1.amazonaws.com's password:
Connected to ec2-52-201-249-4.compute-1.amazonaws.com.
sftp> pwd
Remote working directory: /C:/Users/test-user01
sftp> cd ../../fsxn-share
sftp> ls -l
lrwx******    1 -        -               0 Aug 18 07:57 share1
lrwx******    1 -        -               0 Aug 18 07:57 share2
lrwx******    1 -        -               0 Aug 18 07:57 share3
sftp> put test.txt share1/test.txt
Uploading test.txt to /C:/fsxn-share/share1/test.txt
test.txt                      100%    5     0.0KB/s   00:00
sftp> put test.txt share2/test.txt
Uploading test.txt to /C:/fsxn-share/share2/test.txt
test.txt                      100%    5     0.0KB/s   00:00
sftp> put test.txt share3/test.txt
Uploading test.txt to /C:/fsxn-share/share3/test.txt
dest open "/C:/fsxn-share/share3/test.txt": Permission denied
sftp>
sftp> ls -l share1
-rw-******    1 -        -               5 Aug 18 08:01 test.txt
sftp> ls -l share3
lrwx------    ? 0        0               0 Aug 18 16:57 share3
sftp>
sftp> get share2/test.txt
Fetching /C:/fsxn-share/share2/test.txt to test.txt
test.txt                      100%    5     0.0KB/s   00:00
sftp>
sftp> get share3/test.txt
File "/C:/fsxn-share/share3/test.txt" not found.
test-user03
>  sftp 'corp.non-97.net\test-user03'@ec2-52-201-249-4.compute-1.amazonaws.com
corp.non-97.net\test-user03@ec2-52-201-249-4.compute-1.amazonaws.com's password:
Connected to ec2-52-201-249-4.compute-1.amazonaws.com.
sftp> cd ../../fsxn-share
sftp> ls -l
lrwx******    1 -        -               0 Aug 18 07:57 share1
lrwx******    1 -        -               0 Aug 18 07:57 share2
lrwx******    1 -        -               0 Aug 18 07:57 share3
sftp> put test.txt share2/test.txt
Uploading test.txt to /C:/fsxn-share/share2/test.txt
dest open "/C:/fsxn-share/share2/test.txt": Permission denied
sftp> put test.txt share3/test.txt
Uploading test.txt to /C:/fsxn-share/share3/test.txt
dest open "/C:/fsxn-share/share3/test.txt": Permission denied
sftp>
sftp> ls -l share2
lrwx------    ? 0        0               0 Aug 18 16:57 share2
sftp> ls -l share3
-rw-******    1 -        -               5 Aug 18 07:59 test.txt
sftp>
sftp> get share3/test.txt
Fetching /C:/fsxn-share/share3/test.txt to test.txt
test.txt                      100%    5     0.0KB/s   00:00
sftp>
sftp> cd share2
stat remote: Permission denied

こちらは問題なく、SMBファイル共有のACLに従い、アクセスできたことを確認できました。

chrootで制限できないのが気になりますが、これなら運用的にも回りそうです。

SFTP接続時にABEが効いているかどうか

SFTP接続時にABEが効いているかどうかも確認します。

share2配下にdirというディレクトリを作成し、ACLにtest-user02をフルコントロールで拒否するACEを追加します。

39.test-user02を拒否するACE.png

SFTPを使ってtest-user01とtest-user02でそれぞれshare2にアクセスしたときの結果を確認します。

test-user01
>  sftp 'corp.non-97.net\test-user01'@ec2-52-201-249-4.compute-1.amazonaws.com
corp.non-97.net\test-user01@ec2-52-201-249-4.compute-1.amazonaws.com's password:
Connected to ec2-52-201-249-4.compute-1.amazonaws.com.
sftp> cd ../../fsxn-share/share2
sftp> ls -l
drwx******    1 -        -               0 Aug 19 00:35 dir
-rw-******    1 -        -               5 Aug 18 08:01 test.txt
test-user02
>  sftp 'corp.non-97.net\test-user02'@ec2-52-201-249-4.compute-1.amazonaws.com
corp.non-97.net\test-user02@ec2-52-201-249-4.compute-1.amazonaws.com's password:
Connected to ec2-52-201-249-4.compute-1.amazonaws.com.
sftp> cd ../../fsxn-share
sftp> ls -l
lrwx******    1 -        -               0 Aug 18 07:57 share1
lrwx******    1 -        -               0 Aug 18 07:57 share2
lrwx******    1 -        -               0 Aug 18 07:57 share3
sftp> cd share2
sftp> ls -l
-rw-******    1 -        -               5 Aug 18 08:01 test.txt

test-user02の場合はdirフォルダが表示されませんでした。ABEがしっかり効いていますね。

Windows ServerからSMBサーバーにアクセスする際に暗号化を強制化しても動作できるか

Windows ServerからSMBサーバーにアクセスする際に暗号化を強制化しても動作できるかも確認します。

以下記事を参考にSMBの暗号化を強制化します。

https://dev.classmethod.jp/articles/smb-encryption-settings-in-amazon-fsx-for-netapp-ontap/

::> vserver cifs security show -fields is-smb-encryption-required
vserver is-smb-encryption-required
------- --------------------------
svm     false

::> vserver cifs security modify -is-smb-encryption-required true

::> vserver cifs security show -fields is-smb-encryption-required
vserver is-smb-encryption-required
------- --------------------------
svm     true

SMBの暗号化を強制化後、SFTPでshare1にアクセスします。

>  sftp 'corp\test-user01'@ec2-52-201-249-4.compute-1.amazonaws.com
corp\test-user01@ec2-52-201-249-4.compute-1.amazonaws.com's password:
Connected to ec2-52-201-249-4.compute-1.amazonaws.com.
sftp> cd ../../fsxn-share/share1
sftp> ls -l
-rw-******    1 -        -               5 Aug 18 08:01 test.txt
sftp> get test.txt
Fetching /C:/fsxn-share/share1/test.txt to test.txt
test.txt         100%    5     0.0KB/s   00:00

ONTAP CLIでその時のセッションを確認します。

::> cifs session show -instance

Vserver: svm

                            Node: FsxId0480a4843e2853b1f-01
                      Session ID: 11796616273943593015
                   Connection ID: 1293702520
    Incoming Data LIF IP Address: 10.0.8.12
          Workstation IP Address: 10.0.0.34
        Authentication Mechanism: Kerberos
           User Authenticated as: domain-user
                    Windows User: CORP\test-user01
                       UNIX User: pcuser
                     Open Shares: 2
                      Open Files: 1
                      Open Other: 0
                  Connected Time: 6s
                       Idle Time: 1s
                Protocol Version: SMB3_1
          Continuously Available: No
               Is Session Signed: false
                    NetBIOS Name: -
           SMB Encryption Status: encrypted
               Large MTU Enabled: true
                Connection Count: 1
                   Active Shares: ipc$, share1

認証はKerberos認証でSMBセッションは暗号化されていることが分かりますね。

SFTPの鍵認証

鍵認証するまでのステップ

今までの検証から十分運用として乗せられそうでしたが、気になるのはパスワード認証をしているところです。

対話式で使用するなら気にならないかもしれませんが、スクリプトの中でSFTPの処理をさせたいなら鍵認証をしたいでしょう。

ということで、ドメインユーザー毎に設定した鍵を使って認証するようにしてみます。なお、鍵認証をした際にはKerberosのチケットを要求してくれるかは微妙です。あくまでドメインユーザー上の属性の値を使って鍵認証をしているだけなのでKerberos認証によるチケットのやり取りは行わないとは考えます。

鍵認証するまでのステップは以下のとおりです。

  • スキーママスターの確認
  • OIDの取得
  • 属性の作成
  • クラスの作成
  • ユーザークラスの紐付け
  • 公開鍵の登録
  • AuthorizedKeysCommandに対応したOpenSSHのインストール
  • SSH認証時に公開鍵取得用スクリプトの作成

ADのスキーマには公開鍵を登録するような属性はありません。ADの属性は以下にまとまってます。

https://learn.microsoft.com/ja-jp/windows/win32/adschema/attributes-all

そのため、今回は属性を追加 = スキーマ拡張を行います。スキーマを拡張するタイミングは以下にまとまっています。

https://learn.microsoft.com/ja-jp/windows/win32/ad/when-to-extend-the-schema

また、スキーマ拡張時の注意点は以下に記載されています。

https://learn.microsoft.com/ja-jp/windows/win32/ad/impact-of-schema-changes

もっとも注意すべきポイントとしてはスキーマオブジェクトは追加すると削除できないことでしょう。

スキーマオブジェクトの追加を元に戻すことはできません。 新しいクラスまたは属性オブジェクトがスキーマに追加された場合、削除することはできません。 既存の属性またはクラスを無効にすることはできますが、削除することはできません。 詳細については、 「既存のクラスと属性の無効化」 を参照してください。 クラスまたは属性を無効にしても、クラスまたは属性の既存のインスタンスには影響しませんが、新しいインスタンスは作成されません。 無効になっていないクラスに含まれている属性を無効にすることはできません。

スキーマ変更の影響 - Win32 apps | Microsoft Learn

スキーマ拡張にあたっては以下も参考になります。

https://learn.microsoft.com/ja-jp/windows/win32/ad/how-to-extend-the-schema

スキーママスターの確認

スキーマの更新はスキーママスターのFSMOの役割を持つAD DCにアクセスする必要があります。以下コマンドでスキーママスターを確認しておきます。(今回は1AD DCなので特に気にする必要なし)

> netdom /query fsmo
Schema master               EC2AMAZ-75JBQCK.corp.non-97.net
Domain naming master        EC2AMAZ-75JBQCK.corp.non-97.net
PDC                         EC2AMAZ-75JBQCK.corp.non-97.net
RID pool manager            EC2AMAZ-75JBQCK.corp.non-97.net
Infrastructure master       EC2AMAZ-75JBQCK.corp.non-97.net
The command completed successfully.

今回は行いませんが複数AD DCが動作している場合は、スキーマのレプリケーションを停止させて、もしものためにロールバックできるようにしておくことが良いでしょう。

OIDの取得

次に、OIDの取得を行います。

通常、独自のOIDを使用したい場合はOIDの申請を行うことになります。

ルート オブジェクト識別子 (OID) を取得するには、国際標準機関 (ISO) の名前登録機関に要求することをお勧めします。 これは 1 回限りのアクションです。ルート OID を取得した場合、定義されている OID 領域は自分用であり、自分で管理できます。

通常は、組織名の登録とルート OID の受信に関連する料金が発生します。 料金と登録ポリシーは、国/地域によって異なります。 米国では、ISO NRA は米国国立標準研究所 (ANSI) です。 ANSI 登録手順と料金スケジュールの詳細については、ANSI の Web サイトを参照してください。 ISO メインには、ISO Web サイトのメンバー組織の一覧が含まれています。 米国外にいる場合は、お客様の国/地域の ISO メンバー組織に名前登録情報を問い合わせる必要があります。

Microsoft では、登録機関に登録されていない一意の OID を生成するスクリプトを提供しています。 この方法は、外部関係者が OID 登録について問い合わせない独自のフォレストで使用するスキーマ拡張機能に十分です。 このような基本 OID を作成する方法の詳細については、「Microsoft からのオブジェクト識別子の取得」を参照してください。

ISO 名登録機関からのルート OID の取得 - Win32 apps | Microsoft Learn

ただし、紹介されているとおり、Microsoftが提供しているスクリプトを使用することでOIDを生成することが可能です。スクリプトは以下Microsoft公式ドキュメントで紹介されています。

https://learn.microsoft.com/ja-jp/windows/win32/ad/obtaining-an-object-identifier-from-microsoft

AD DC上でこちらのVBSスクリプトを作成し、実行します。

> .\oidgen.vbs
> cat .\Desktop\oidInfo.txt
Your root OID is:
1.2.840.113556.1.8000.2554.42871.35914.2838.17036.37913.15512078.14705549

This prefix should be used to name your schema attributes and classes. For example: if your prefix is "Microsoft", you should name schema elements like "microsoft-Employee-ShoeSize". For more information on the prefix, view the Schema Naming Rules in the server Application Specification (http://www.microsoft.com/windowsserver2003/partners/isvs/appspec.mspx).

You can create subsequent OIDs for new schema classes and attributes by appending a .X to the OID where X may be any number that you choose.  A common schema extension scheme generally uses the following structure:
If your assigned OID was: 1.2.840.113556.1.8000.2554.999999

then classes could be under: 1.2.840.113556.1.8000.2554.999999.1
which makes the first class OID: 1.2.840.113556.1.8000.2554.999999.1.1
the second class OID: 1.2.840.113556.1.8000.2554.999999.1.2     etc...

Using this example attributes could be under: 1.2.840.113556.1.8000.2554.999999.2
which makes the first attribute OID: 1.2.840.113556.1.8000.2554.999999.2.1
the second attribute OID: 1.2.840.113556.1.8000.2554.999999.2.2     etc...
.
.
(以下略)
.
.

1.2.840.113556.1.8000.2554.42871.35914.2838.17036.37913.15512078.14705549が生成されたroot OIDです。

また、実行するとDllRegisterServer in schmmgmt.dll succeededとポップアップが表示されます・

7.DllRegisterServer in schmmgmt.dll succeeded.png

属性の作成

次に属性を作成します。

下準備として Active Directoryスキーマ管理スナップインを追加します。

PowerShellでmmcと叩き、MMC管理コンソールを起動します。

File-Add/Remote Snap-inをクリックします。

8.Add:Remote Snap-in.png

Active Directory Schemaを追加します。

9.Active Directory Schemaのスナップインの追加.png

追加後、Create Attributeをクリックします。

10.Create Attribute.png

「スキーマオブジェクトの変更は永続的な操作です」と警告が表示されます。続行します。

11.Schema Object Creation.png

non97-sshPublicKeysという属性を作成します。

29.non97-sshPublicKeysの作成.png

属性とクラスの名前付けに従い命名しました。OIDはの末尾は2.2です。

https://learn.microsoft.com/ja-jp/windows/win32/ad/naming-attributes-and-classes

属性のSyntaxは以下Microsoft公式ドキュメントをご覧ください。

https://learn.microsoft.com/ja-jp/windows/win32/adschema/syntaxes

属性が作成されたことを確認します。

30.non97-sshPublicKeysが作成されたこと.png

クラスの作成

続けてクラスも作成します。

Create Classをクリックします。

14.Create Class.png

属性追加時と同様の警告が表示されます。続行します。

15.Schema Object Creation.png

non97-ldapPublicKeyという補助クラスを作成します。OIDの末尾は1.2です。

31.non97-ldapPublicKeyの作成.png

Optionalとして先ほど作成した属性であるnon97-sshPublicKeysを追加します。

32.Optionalにnon-97-sshPublicKeysを追加.png

補助クラスが作成されたことを確認します。

33.non97-ldapPublicKeyが作成されたこと.png

ユーザークラスに補助クラスを追加

ユーザークラスに補助クラスを追加します。

userクラスに補助クラスを追加します。

19.userクラスに補助クラスを追加.png

作成した補助クラスnon97-ldapPublicKeyを追加します。

34.non97-ldapPublicKeyを追加.png

補助クラスに追加されたことを確認します。

35.non97-ldapPublicKeyが補助クラスに追加されたこと.png

スキーマの反映

スキーマの反映を行います。

現時点ではまだnon-97-sshPublicKeysは使用できません。

36.non-97-sshPublicKeysはまだ登録できない.png

スキーマの反映をさせるためにスキーマキャッシュを削除します。

ADSI Editを起動します。起動したらAction-Connect toをクリックします。

23.ADSI Edit.png

Select a well known Naming ContextSchemaを選択して接続します。

24.Conncection Settings.png

スキーマを選択してUpdate Schema Nowをクリックします。

25.Update Schema Now.png

The schema cache was updated successfullyとキャッシュが更新されたことを確認します。

26.The schema cache was updated successfully.png

しばらく待つと属性に反映されます。どうしても反映されない場合はAD DCを再起動させます。

スキーマで追加変更したオブジェクトをCLIで確認した結果は以下のとおりです。

42.スキーマで追加変更したオブジェクトの確認.png

公開鍵の登録

ユーザーの属性にnon97-sshPublicKeysが追加されていることを確認します。

37.属性にnon97-sshPublicKeysが追加されたこと.png

各ドメインユーザーごとに作成した公開鍵を登録します。

38.公開鍵の登録.png

AuthorizedKeysCommandに対応したOpenSSHのインストール

あとはSFTPで鍵認証する際にユーザーの属性から公開鍵を取得するだけです。

その時に使用するのがAuthorizedKeysCommandです。

ただし、Windows標準のOpenSSHである8.1p1はAuthorizedKeysCommandをサポートしていません。そのため、AuthorizedKeysCommandに対応したOpenSSHのインストールを行う必要があります。

ベータ版にはなりますが、wingetを用いることでOpenSSH 8.9.1.0以降のバージョンのものは使用することが可能です。

https://github.com/PowerShell/Win32-OpenSSH/wiki/Install-Win32-OpenSSH

実際に試してみましょう。

まず、Windows標準のOpenSSHをアンインストールします。

> Remove-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

Path          :
Online        : True
RestartNeeded : True

> Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

Path          :
Online        : True
RestartNeeded : False

アンインストール後はOSを再起動します。

続けて、以下記事を参考にwingetをインストールします。

https://dev.classmethod.jp/articles/how-to-use-windows-terminal-on-2022-server-ec2/

.
.
(略)
.
.
Install C:\Users\Administrator.CORP\AppData\Local\Temp\2\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle
  : License C:\Users\Administrator.CORP\AppData\Local\Temp\2\76fba573f02545629706ab99170237bc_License1.xml

Path          :
Online        : True
RestartNeeded : False

Install Microsoft.UI.Xaml 2.8.6
Registter Microsoft.DesktopAppInstaller
Remove C:\Users\Administrator.CORP\AppData\Local\Temp\2\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle
Remove C:\Users\Administrator.CORP\AppData\Local\Temp\2\76fba573f02545629706ab99170237bc_License1.xml
Installation complete!

wingetでOpen SSHをインストールします。

> winget search "openssh"
The `msstore` source requires that you view the following agreements before using.
Terms of Transaction: https://aka.ms/microsoft-store-terms-of-transaction
The source requires the current machine's 2-letter geographic region to be sent to the backend service to function properly (ex. "US").

Do you agree to all the source agreements terms?
[Y] Yes  [N] No: y
Name         Id                     Version Match        Source
---------------------------------------------------------------
SSHells      dzonder.sshells        0.1.1   Tag: openssh winget
OpenSSH Beta Microsoft.OpenSSH.Beta 9.5.0.0              winget

> winget install "OpenSSH Beta"
Found OpenSSH Beta [Microsoft.OpenSSH.Beta] Version 9.5.0.0
This application is licensed to you by its owner.
Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Downloading https://github.com/PowerShell/Win32-OpenSSH/releases/download/v9.5.0.0p1-Beta/OpenSSH-Win64-v9.5.0.0.msi
  ██████████████████████████████  5.47 MB / 5.47 MB
Successfully verified installer hash
Starting package install...
Successfully installed

OpenSSH Beta 9.5.0.0をインストールできました。

sshdの起動および自動起動の有効化を行います。

> Start-Service sshd
> Set-Service -Name sshd -StartupType 'Automatic'

サービスのパスは以下のとおりです。

> Get-WmiObject win32_service | Where-Object {$_.name -eq 'sshd'} | Select-Object Name, DisplayName, PathName, StartMode

Name DisplayName        PathName                            StartMode
---- -----------        --------                            ---------
sshd OpenSSH SSH Server "C:\Program Files\OpenSSH\sshd.exe" Auto

SSH認証時の公開鍵取得用スクリプトの作成

AuthorizedKeysCommandで実行する、SSH認証時の公開鍵取得用スクリプトを作成します。

C\Program Files\OpenSSH\Get-SshPublickey.ps1
[CmdletBinding()]
Param(
    [Parameter(Mandatory = $true, Position = 0)]
    [string]$Username,

    [Parameter(Mandatory = $false)]
    [string]$SSHPublicKeyAttribute = "non97-sshPublicKeys"
)

function Get-UserSSHPublicKey {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory = $true)]
        [string]$SamAccountName,

        [Parameter(Mandatory = $true)]
        [string]$AttributeName
    )

    try {
        $filter = "(&(objectClass=user)(sAMAccountName=$SamAccountName))"
        $searcher = New-Object System.DirectoryServices.DirectorySearcher($filter)
        $searcher.PropertiesToLoad.Add($AttributeName) | Out-Null

        $result = $searcher.FindOne()
        if ($null -eq $result) {
            Write-Warning "User not found: $SamAccountName"
            return $null
        }

        return $result.Properties[$AttributeName]
    }
    catch {
        Write-Error "An error occurred while searching for the user: $_"
        return $null
    }
}

try {
    $samAccountName = $Username.Split("\")[-1]
    $sshPublicKey = Get-UserSSHPublicKey -SamAccountName $samAccountName -AttributeName $SSHPublicKeyAttribute

    if ($null -ne $sshPublicKey) {
        Write-Output $sshPublicKey
    }
    else {
        Write-Warning "No $SSHPublicKeyAttribute found for user: $samAccountName"
    }
}
catch {
    Write-Error "An unexpected error occurred: $_"
}

試しに実行します。

> pwd

Path
----
C:\Program Files\OpenSSH

> .\Get-SshPublickey.ps1 corp.non-97.net\Administrator
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHX+OaU8EgTEWiWmHamIpJI+HSBPEPLsLNii6Bpgi+KQ corp_Administrator

> .\Get-SshPublickey.ps1 corp\test-user01
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKHZ75YsZDhXJxt5bK9XvSZ8JEHLY4T32SFKMi4u0UNp corp_test-user01

引数で指定したユーザーの公開鍵を取得できました。

sshd_configの修正

sshd_configの修正を行います。変更箇所は以下のとおりです。

>  diff -u sshd_config_default sshd_config
--- sshd_config_default 2024-08-20 08:33:46
+++ sshd_config 2024-08-20 08:33:32
@@ -31,14 +31,17 @@
 #MaxAuthTries 6
 #MaxSessions 10

-#PubkeyAuthentication yes
+PubkeyAuthentication yes

 # The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
 # but this is overridden so installations will only check .ssh/authorized_keys
-AuthorizedKeysFile .ssh/authorized_keys
+#AuthorizedKeysFile .ssh/authorized_keys

 #AuthorizedPrincipalsFile none

+AuthorizedKeysCommand C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -NonInteractive -File "C:\Program Files\OpenSSH\Get-SshPublickey.ps1" -username %u
+AuthorizedKeysCommandUser "system"
+
 # For this to work you will also need host keys in %programData%/ssh/ssh_known_hosts
 #HostbasedAuthentication no
 # Change to yes if you don't trust ~/.ssh/known_hosts for
@@ -48,7 +51,7 @@
 #IgnoreRhosts yes

 # To disable tunneled clear text passwords, change to no here!
-#PasswordAuthentication yes
+PasswordAuthentication no
 #PermitEmptyPasswords no

 # GSSAPI options
@@ -84,5 +87,7 @@
 # PermitTTY no
 # ForceCommand cvs server

-Match Group administrators
-       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
\ No newline at end of file
+AllowGroups "corp\Domain Admins" corp\FsxAdminGroup corp\domain-local
+
+Match Group corp\*
+       ForceCommand internal-sftp

sshd_configはC:\ProgramData\ssh配下に配置します。

配置後、sshdを再起動します。

SFTPによるファイル操作

動作確認をしてみましょう。

まずは鍵を指定していない場合です。

>  sftp 'corp.non-97.net\Administrator'@ec2-52-201-249-4.compute-1.amazonaws.com
corp.non-97.net\\Administrator@ec2-52-201-249-4.compute-1.amazonaws.com: Permission denied (publickey,keyboard-interactive).
Connection closed

パスワード認証は許可していないので弾かれました。意図した挙動です。

次に鍵認証を行います。

>  sftp -i ./corp_Administrator 'corp.non-97.net\Administrator'@ec2-52-201-249-4.compute-1.amazonaws.com
Connected to ec2-52-201-249-4.compute-1.amazonaws.com.
sftp> pwd
Remote working directory: /C:/Users/Administrator.CORP

問題なく認証できましたね。

Windowsのイベントログからも認証の様子は確認できました。

40.鍵認証成功時.png

ちなみにログレベルをデバッグに変更すると、以下のようにAuthorizedKeysCommandが正常実行できたことを確認できます。

41.デバッグログ有効化時.png

それではFSxNのSMBファイル共有のシンボリックリンクにアクセスします。

sftp> cd ../../fsxn-share
sftp> ls -l
lrwx******    1 -        -               0 Aug 18 07:57 share1
lrwx******    1 -        -               0 Aug 18 07:57 share2
lrwx******    1 -        -               0 Aug 18 07:57 share3
sftp> ls -l share2
lrwx------    ? 0        0               0 Aug 18 16:57 share2
sftp> ls -l share3
lrwx------    ? 0        0               0 Aug 18 16:57 share3
sftp> cd ./share2
stat remote: Permission denied
sftp> exit

はい、拒否されました。やはり鍵認証をしている都合上、Kerberosのチケットを入手していないためSMBファイル共有にはアクセスできないようです。

最後に念の為、他ユーザーの鍵を使って認証できないことを確認します。

>  sftp -i ./corp_test-user01 'corp.non-97.net\Administrator'@ec2-52-201-249-4.compute-1.amazonaws.com
corp.non-97.net\\Administrator@ec2-52-201-249-4.compute-1.amazonaws.com: Permission denied (publickey,keyboard-interactive).
Connection closed

拒否されました。意図した挙動です。

FSxNにSFTPで接続したい場合は運用や周囲の環境を変更できないかも検討しよう

Amazon FSx for NetApp ONTAPをマウントしたWindows ServerをSFTPサーバーとして動作させてみました。

運用には組み込める形かと考えます。FSxWでも同様の対応は可能でしょう。

ただし、chrootを効かせることができなかったり、鍵認証ができなかったりと気になるところはあります。実際に運用に組み込む際は最小権限のドメインユーザーを用意して、操作させることになると考えます。

また、SFTPを無理矢理使わないには越したことがないので、SFTPを使わずに要件を満たせられるように、運用や周囲の環境を変更できないかも検討しましょう。

この記事が誰かの助けになれば幸いです。

以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!

この記事をシェアする

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.